-
Notifications
You must be signed in to change notification settings - Fork 6.8k
[MXNET-978] n-th order gradient test support. #15611
[MXNET-978] n-th order gradient test support. #15611
Conversation
While working on a PR (I don't exactly remember which one), test for incorrect implementation of second order gradient was passing due to the very small values. However as sanity check, when I checked for its third order gradient, the assertion failed allowing to catch the issue. So I think it would be better to check for the order being implemented and one more (computed by autograd) as a sanity check. Would like to know your thoughts about the same. Thank You. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice approach.
head_grad = nd.random.normal(shape=x.shape) | ||
y = autograd.grad(heads=y, variables=x, head_grads=head_grad, | ||
create_graph=True, retain_graph=True)[0] | ||
if current_order in orders: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If current_order is not in orders we might have problem zipping? Is there a case where you wou want 1st and 3rd order but not second?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there would be an issue in that case (will confirm it later though).
If current_order
is not in orders
case is checked here,
https://github.com/apache/incubator-mxnet/blob/1f74614391e182e299e2fdcce1036515c4e5fb4f/tests/python/unittest/test_higher_order_grad.py#L41-L42
where first order is not asserted (as per the arguments).
The main thing is that elements in orders
should be monotonically increasing and they should correspond to elements of the grad_ops
.
We can also use a dictionary {order: corresponding grad op, ... }
which removes the above requirement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have confirmed, that
check_nth_order_unary(array, sin, [grad_op, grad_grad_grad_op], [1, 3])
following works.
assert_almost_equal(expected_grad_grad, x.grad.asnumpy()) | ||
for current_order in range(1, order+1): | ||
head_grad = nd.random.normal(shape=x.shape) | ||
y = autograd.grad(heads=y, variables=x, head_grads=head_grad, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better name instead of mutating y?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One option I can think of is, at the start of for loop we'll have computed_grad = y
(which is deceiving) and replace y
by computed_grad
in the for loop.
Up for suggestions.
check_nth_order_unary(x, op, grad_grad_op, 2) | ||
|
||
|
||
def check_nth_order_unary(x, op, grad_ops, orders): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add docstring?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added the docstring. Could you please take a look to see if it needs more polishing.
Thank You.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
…to develop/higher-order-grad/test-support
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
# Manual head_grads. | ||
y_grad = nd.random.normal(shape=x.shape) | ||
head_grad_grads = nd.random.normal(shape=x.shape) | ||
order = max(orders) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If orders is monotonically increasing, should this just be orders[-1]?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. That will work as well. But I felt max(orders)
stated the intent more clearly.
Ping @sxjscience for review. |
@sxjscience Gentle ping for review:) |
* n-th order grad test support * use check_nth_order_unary for second order check * add docstring to check_nth_order_unary * retrigger CI * add assertions for requirements of orders * fix assert condition * retrigger CI
* n-th order grad test support * use check_nth_order_unary for second order check * add docstring to check_nth_order_unary * retrigger CI * add assertions for requirements of orders * fix assert condition * retrigger CI
Description
n-th order gradient test support function.
Checklist
Essentials
Please feel free to remove inapplicable items for your PR.
Changes